
package com.xuelang.pipeline.artifact.app.resource.impl;

import cn.hutool.core.util.IdUtil;
import com.xuelang.hiforce.base.tracing.TracingUtils;
import com.xuelang.pipeline.artifact.app.nexus3v1.enums.Nexus3RepositoryTypeEnum;
import com.xuelang.pipeline.artifact.app.resource.ArtifactProxyService;
import com.xuelang.pipeline.artifact.app.resource.InstanceRepositoryService;
import com.xuelang.pipeline.artifact.app.resource.converter.ArtifactProxyDTOToArtifactProxyConverter;
import com.xuelang.pipeline.artifact.client.common.constant.Constant;
import com.xuelang.pipeline.artifact.client.common.request.PageParam;
import com.xuelang.pipeline.artifact.client.common.result.PageRecord;
import com.xuelang.pipeline.artifact.client.common.util.BizAssert;
import com.xuelang.pipeline.artifact.client.resource.dto.ArtifactProxyDTO;
import com.xuelang.pipeline.artifact.client.resource.dto.ArtifactProxyQuery;
import com.xuelang.pipeline.artifact.client.resource.enums.ArtifactToolEnum;
import com.xuelang.pipeline.artifact.domain.resource.ArtifactProxy;
import com.xuelang.pipeline.artifact.domain.resource.service.ArtifactProxyDomainService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 制品仓库代理服务实现类
 *
 * @author xiwen.zxg
 * @since 2024/5/15
 */
@Service
public class ArtifactProxyServiceImpl implements ArtifactProxyService {

    @Autowired
    ArtifactProxyDomainService artifactProxyDomainService;
    @Autowired
    InstanceRepositoryService instanceRepositoryService;

    @Override
    public PageRecord<ArtifactProxyDTO> pageList(PageParam<ArtifactProxyQuery> dtoPageParam) {
        ArtifactProxyQuery condition = dtoPageParam.getCondition();
        condition = condition == null ? new ArtifactProxyQuery() : condition;
        BizAssert.notNull(condition.getGroupArtifactUuid(), "分组仓库UUID不能为空");
        BizAssert.notNull(condition.getArtifactType(), "代理仓库类型不能为空");
        PageRecord<ArtifactProxy> pageRecord = artifactProxyDomainService.pageList(
                dtoPageParam.getCurrentPage(),
                dtoPageParam.getPageSize(),
                condition);
        return new PageRecord<>(
                pageRecord.getCurrentPage(),
                pageRecord.getPageSize(),
                pageRecord.getTotalCount(),
                pageRecord.getTotalPages(),
                pageRecord.getRecords().stream().map(ArtifactProxyDTOToArtifactProxyConverter.INSTANCE::artifactProxyToArtifactProxyDTO).collect(Collectors.toList()));
    }

    @Override
    public List<ArtifactProxyDTO> list(ArtifactProxyQuery artifactProxyQuery) {
        BizAssert.notNull(artifactProxyQuery.getGroupArtifactUuid(), "分组仓库UUID不能为空");
        BizAssert.notNull(artifactProxyQuery.getArtifactType(), "代理仓库类型不能为空");
        return artifactProxyDomainService.list(artifactProxyQuery).stream().map(ArtifactProxyDTOToArtifactProxyConverter.INSTANCE::artifactProxyToArtifactProxyDTO).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(ArtifactProxyDTO artifactProxyDTO) {

        // 判断当前代理仓库是否绑定过，不允许重复绑定同样的代理仓库
        BizAssert.isFalse(artifactProxyDomainService.existsCurrentProxy(
                artifactProxyDTO.getGroupArtifactUuid(),
                artifactProxyDTO.getSourceArtifactUuid()
                ),
                "当前代理仓库已绑定过，不允许重复绑定");

        ArtifactProxy proxy = ArtifactProxyDTOToArtifactProxyConverter.INSTANCE.artifactProxyDTOToArtifactProxy(artifactProxyDTO);
        proxy.setCreatorId(TracingUtils.getUserId());
        proxy.setUpdaterId(TracingUtils.getUserId());
        proxy.setProxyArtifactUuid(IdUtil.simpleUUID());
        proxy.setProxyInstanceRepoName((
                Nexus3RepositoryTypeEnum.PROXY.name()
                + Constant.DEFAULT_MIDDLE_SEPARATOR + artifactProxyDTO.getGroupInstanceRepoName()
                + Constant.DEFAULT_MIDDLE_SEPARATOR + artifactProxyDTO.getSourceArtifactCode()
               ).toLowerCase());

        boolean save = artifactProxyDomainService.save(proxy);
        if (save) {
            final List<String> proxyInstanceRepoNameList = new ArrayList<>();
            // 获取列表的PROXY_INSTANCE_REPO_NAME
            Optional.ofNullable(artifactProxyDomainService.list(ArtifactProxyQuery.builder().groupArtifactUuid(artifactProxyDTO.getGroupArtifactUuid()).build())).ifPresent(
                    artifactProxyList -> artifactProxyList.forEach(artifactProxy -> proxyInstanceRepoNameList.add(artifactProxy.getProxyInstanceRepoName())));
            // 根据仓库类型去中间件实例创建对应代理仓库：Nexus3-仓库、Harbor-项目
            instanceRepositoryService.createProxyRepository(
                    ArtifactToolEnum.ArtifactTypeEnum.getByKey(artifactProxyDTO.getArtifactType()),
                    proxy,
                    proxyInstanceRepoNameList
            );
        }
        return save;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delete(String proxyArtifactUuid) {
        BizAssert.notNull(proxyArtifactUuid, "uuid不能为空");
        // 根据仓库类型去中间件实例删除对应代理仓库：Nexus3-仓库、Harbor-项目
        ArtifactProxy query = artifactProxyDomainService.query(proxyArtifactUuid);
        boolean delete = artifactProxyDomainService.delete(proxyArtifactUuid);
        if (query != null && delete) {
            instanceRepositoryService.deleteProxyRepository(
                    ArtifactToolEnum.ArtifactTypeEnum.getByKey(query.getArtifactType()),
                    query.getProxyInstanceRepoName());
        }
        return delete;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean update(ArtifactProxyDTO artifactProxyDTO) {
        BizAssert.notNull(artifactProxyDTO.getProxyArtifactUuid(), "uuid不能为空");
        ArtifactProxy tool = ArtifactProxyDTOToArtifactProxyConverter.INSTANCE.artifactProxyDTOToArtifactProxy(artifactProxyDTO);
        tool.setCreatorId(TracingUtils.getUserId());
        tool.setUpdaterId(TracingUtils.getUserId());
        return artifactProxyDomainService.update(tool);
    }

    @Override
    public ArtifactProxyDTO query(String proxyArtifactUuid) {
        BizAssert.notNull(proxyArtifactUuid, "uuid不能为空");
        ArtifactProxy tool = artifactProxyDomainService.query(proxyArtifactUuid);
        return ArtifactProxyDTOToArtifactProxyConverter.INSTANCE.artifactProxyToArtifactProxyDTO(tool);
    }


}
